package com.lovezy.platform.wiki.service.impl;

import com.github.pagehelper.Page;
import com.lovezy.platform.core.base.query.Pager;
import com.lovezy.platform.core.base.service.MapperService;
import com.lovezy.platform.core.exception.ServiceException;
import com.lovezy.platform.core.mq.MessageProducer;
import com.lovezy.platform.filestore.service.FileHelper;
import com.lovezy.platform.message.push.DefaultPushMessage;
import com.lovezy.platform.message.push.PushEntity;
import com.lovezy.platform.message.push.PushIType;
import com.lovezy.platform.message.push.PushMessage;
import com.lovezy.platform.wiki.enums.GameOperationType;
import com.lovezy.platform.wiki.form.GameOperationForm;
import com.lovezy.platform.wiki.form.WikiNoticeForm;
import com.lovezy.platform.wiki.mapper.GameOperationMapper;
import com.lovezy.platform.wiki.model.Game;
import com.lovezy.platform.wiki.model.GameOperation;
import com.lovezy.platform.wiki.model.GameOperationExample;
import com.lovezy.platform.wiki.service.GameOperationService;
import com.lovezy.platform.wiki.service.GameService;
import com.lovezy.platform.wiki.vo.GameOperationVo;
import com.lovezy.platform.wiki.vo.WikiVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;

import static com.lovezy.platform.core.utils.ObjectUtil.copyTo;
import static com.lovezy.platform.core.utils.ObjectUtil.nonNull;
import static java.util.stream.Collectors.toList;

/**
 * 百科运营服务
 * Created by jin on 2018/1/4.
 */
@Service
@Slf4j
public class GameOperationServiceImpl extends MapperService<GameOperation,Integer,GameOperationMapper> implements GameOperationService{

    @Autowired
    GameService gameService;

    @Autowired
    FileHelper fileHelper;

    @Autowired
    @Qualifier("pushMessageProducer")
    private MessageProducer pushMessageProducer;

    @Override
    public void settingOperationGame(GameOperationForm form){
        Integer gameId = form.getGameId();
        nonNull("游戏ID不能为空",gameId);
        GameOperation gameOperation = getOrInit(gameId);
        gameOperation.setNewGame(parseFrontInputFormData(form.getNewGame(),gameOperation.getNewGame()));
        gameOperation.setHotGame(parseFrontInputFormData(form.getHotGame(), gameOperation.getHotGame()));
        gameOperation.setSearchGame(parseFrontInputFormData(form.getSearchGame(), gameOperation.getSearchGame()));
        mapper.updateByPrimaryKey(gameOperation);
    }

    @Override
    public GameOperationVo settingDetail(Integer gameId) {
        nonNull("游戏ID不能为空",gameId);
        GameOperation game = getOrInit(gameId);
        return copyTo(game, new GameOperationVo());
    }

    private Integer parseFrontInputFormData(Integer input,Integer before) {
        if(input == null) return before;
        return input == 0 ? null : input;
    }

    @Override
    public List<String> findSearchName() {
        GameOperationExample example = new GameOperationExample();
        example.createCriteria()
                .andSearchGameIsNotNull();
        example.setOrderByClause("searchGame");
        Page<GameOperation> searchGame = Pager.doPageAll(() -> mapper.selectByExample(example));

        return searchGame.getResult().stream().map(gameOperation -> {
            Game game = gameService.selectById(gameOperation.getGameId());
            if (game != null) {
                String chineseName = game.getChineseName();
                return StringUtils.hasText(chineseName) ? chineseName : game.getName();
            }
            return null;
        }).filter(Objects::nonNull).collect(toList());
    }

    @Override
    public void resetSetting(byte type) {
        GameOperationType gameOperationType = GameOperationType.valueOf(type);
        if (gameOperationType == null) {
            throw new ServiceException("百科运营类别错误");
        }
        GameOperation gameOperation = new GameOperation();
        GameOperationExample example = new GameOperationExample();
        GameOperationExample.Criteria criteria = example.createCriteria();
        switch (gameOperationType) {
            case HOT:
                gameOperation.setHotGame(null);
                criteria.andHotGameIsNotNull();
                mapper.updateByExample(gameOperation, example);
                break;
            case NEW:
                criteria.andNewGameIsNotNull();
                gameOperation.setNewGame(null);
                mapper.updateByExample(gameOperation, example);
                break;
            case SEARCH:
                criteria.andSearchGameIsNotNull();
                gameOperation.setSearchGame(null);
                mapper.updateByExample(gameOperation, example);
                break;
        }

    }

    @Override
    public List<WikiVo> newOrHotList() {
        List<GameOperation> gameOperations = mapper.newOrHotList();
        return gameOperations.stream().map(gameOperation -> {
            WikiVo wiki = gameService.findWikiById(gameOperation.getGameId());
            if (gameOperation.getHotGame() != null) {
                wiki.setOperationType(GameOperationType.HOT.getType());
            } else if (gameOperation.getNewGame() != null) {
                wiki.setOperationType(GameOperationType.NEW.getType());
            }
            wiki.setLogo(fileHelper.toDownloadUrl(wiki.getLogo()));
            return wiki;
        }).filter(wiki -> wiki.getOperationType() != null).collect(toList());
    }

    private GameOperation getOrInit(Integer gameId) {
        GameOperation gameOperation = mapper.selectByPrimaryKey(gameId);
        if (gameOperation == null) {
            GameOperation newGame = new GameOperation();
            newGame.setGameId(gameId);
            mapper.insert(newGame);
            return newGame;
        }
        return gameOperation;

    }


    @Override
    public void pushWikiNotice(WikiNoticeForm form) {
        WikiVo wiki = gameService.findWikiById(form.getGameId());
        PushMessage<WikiVo> message = new DefaultPushMessage<>();
        message.setContent(form.getContent());
        message.setEntity(new PushEntity<>(PushIType.GAME, wiki));
        pushMessageProducer.send(message);
    }


}
